package com.test.updater.fsm;

import java.lang.ref.WeakReference;

/**
 * Created by lmy on 2015/8/10.
 */

public abstract class FSMMachine {

    protected WeakReference<FSMState> mCurrentState;
    protected Row[] rowTable;

    public FSMMachine() {

    }

    public <E> void dispatchEvent(Class<E> event, Parameter parameter) throws FSMException {
        //mCurrentState.get().exit();
        synchronized (FSMMachine.class) {
            FSMState state = mCurrentState.get();

            if (selectFsmState(event)) {
                if(state != null) {
                    state.exit();
                    state = null;
                }
                mCurrentState.get().enter(parameter);
            } else {
                throw new FSMException(FSMException.FSM_MATCH_NOSTATE_ERRORCODE,
                        FSMException.FSM_MATCH_NOSTATE_ERRORMSG);
                //如果没有匹配就不操作
                //endFsmProcess();
            }
        }
    }

    public void endFsmProcess() {
        synchronized (FSMMachine.class) {
            mCurrentState.get().exit();
            mCurrentState = null;

            finish();
            unInit();
        }

    }

    public abstract boolean init();

    public abstract void start();

    public abstract void unInit();

    public void finish() {
        int size = rowTable.length;
        for (int index = 0; index < size; index++) {
            rowTable[index] = null;
        }
        rowTable = null;
    }

    public <E> boolean selectFsmState(E event) {
        boolean ret = false;

        int size = rowTable.length;
        for (int i = 0; i < size; i++) {
            if (rowTable[i].isMatch(mCurrentState.get(), event)) {
                mCurrentState = rowTable[i].getNextState();
                ret = true;
                break;
            }
        }

        return ret;
    }
}
